﻿//#define debug

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Data;
using System.IO;
using Utilities;
using System.Threading;
using System.Globalization;
using Microsoft.Win32;
using System.Xml.Linq;


namespace WMI
{
    //  TODO
    //  DA IMPLEMENTARE QUESTE CLASSI (SEGNARE CON * QUELLE GIA FATTE)
    //  SEGUIRE IL MIO SCHEMA, (NO DISKDRIVE, è UN CASO A PARTE) E UTILIZZARE NOMI INTELLIGENTI (NO F)
    // * DISKDRIVE 
    // * LOGICALDRIVE
    // * NETWORKCONNECTION          NON SERVE IN QUANTO IL SERVIZIO VIENE AVVIATO COME SISTEMA LOCALE E NON HA DISCHI MAPPATI
    // * ACCOUNT
    // * CDROMDRIVE
    // * COMPUTERSYSTEM
    // * FLOPPYDRIVER (PER I SCARSI)
    // * IPV4ROUTETABLE
    //  * LoggedOnUser 
    //  * LOGONSESSION
    //  * BASEBOARD
    //  * OperatingSystem
    // NO PageFile  deprecata
    // * ParallelPort
    // * PhysicalMemory
    // * PnPEntity
    //  PortableBattery				BOH
    // * Printer
    // * Processor 
    // * Product						
    // * SCSIController
    //  SerialPort					
    // * Share
    // * SoundDevice					
    // * VideoController
    //  WindowsProductActivation		Non c'è l'ho
    //   ED ALTRE ANCORA DA SCEGLIERE.
    //   PRENDERE SOLO PE PROPRIETA IMPORTANTI E SCRIVERE I NOMI GIUSTI
    //   
    //   
    //   
    //   
    //   
    //   


    public static class Utils
    {
        public static DataTable NewTable(string Name, String[] Properties)
        {
            DataTable dt = new DataTable(Name);
            dt.Columns.Add("MachineName");
            dt.Columns.Add("ID");
            dt.Columns.Add("InsertDate");
            foreach (string Property in Properties)
            {
                dt.Columns.Add(Property);
            }
            
            return dt;
        }

        public static DataTable NewTable(String[] Properties)
        {
            DataTable dt = new DataTable("Result");
            foreach (string Property in Properties)
            {
                dt.Columns.Add(Property);
            }

            return dt;
        }

        public static void InsertException(string TableName, string ExceptionMessage)
        {
            int i = 0;
            if (Classes.LocalWMI.Tables[TableName].Rows.Count > 0)
                i = int.Parse(Classes.LocalWMI.Tables[TableName].Rows[Classes.LocalWMI.Tables[TableName].Rows.Count][0].ToString());
            Classes.LocalWMI.Tables[TableName].Rows.Add(new string[] { Environment.MachineName , i.ToString() ,DateTime.Today.ToShortDateString(), "Error", ExceptionMessage });
        }

        public static object GetItemsFromMOArray(object MOSObject)
        {
            string items = string.Empty;
            foreach (string item in MOSObject as string[])
            {
                items += item + " , ";
            }
            return items;
        }
    }
    
    /// <summary>
    /// Classe contenente metodi statici per recuperare le informazioni da WMI
    /// </summary>
    public static class Classes
    {
        
        static ManagementObjectCollection mos;                                             // Collezione di oggetti recuperati da WMI
        public static DataSet LocalWMI = new DataSet(System.Environment.MachineName);      // DataSet contente tutte le tabelle con i dati recuperati da WMI e log. 1 Tabella = 1 Classe Win32_
        static Utilities.Reader reader = new Utilities.Reader();
        static string InstallationFolder = Utilities.Utilities.GetInstallationFolder();
        static bool debug = false;

        public static void GetAllClasses()
        {
            LocalWMI.Tables.Clear();
            Utilities.Utilities.SetCurrentCulture();

            BaseBoard();
            CDROMDrive();
            ComputerSystem();
            DiskDrive();
            FloppyDrive();
            Group();
            IP4RouteTable();
            LogonSession();
            NetworkAdapter();
            NetworkAdapterConfiguration();
            NetworkLoginProfile();
            OperatingSystem();
            ParallelPort();
            PhysicalMemory();
            PnPEntity();
            Printer();
            Processor();
            Product();
            SerialPort();
            Share();
            SoundDevice();
            UserAccount();
            VideoController();     
        }

        /// <summary>
        /// Metodo che effettua una chiamata al WMI utilizzando una query personalizzata
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public static string GetByQuery(string Query)
        {
            List<string> Properties = new List<string>();
            DataSet ds = new DataSet(System.Environment.MachineName);
            mos = new ManagementObjectSearcher(Query).Get();

            foreach (ManagementObject mo in mos)
            {
                if (Properties.Count < 1)
                {   
                    foreach (PropertyData item in mo.Properties)
                    {
                        Properties.Add(item.Name.ToString());
                    }
                    ds.Tables.Add(Utils.NewTable(Properties.ToArray()));
                }

                ds.Tables["Result"].Rows.Add(
                                        (from item in Properties select mo[item]).ToArray()
                                      );
            }
            return ds.GetXml();
        }

        public static void GetClassesByScheduling()
        {
            Utilities.Utilities.SetCurrentCulture();
            reader.RunScheduled();
        }

        /// <summary>
        /// Classe: Win32_NetworkConnection. Elenca tutte le unità di rete mappate sul sistema locale
        /// </summary>
        
        /**     public static void NetworkConnection()
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkConnection").Get();

                String[] NetworkConnectionProperties = { "ConnectionState", "ConnectionType", "DisplayType", "LocalName", "Name", "Persistent"
                                             , "ProviderName", "RemoteName", "RemotePath", "ResourceType", "Status", "UserName"};

                LocalWMI.Tables.Add(Utils.NewTable("NetworkConnection", NetworkConnectionProperties));

                try
                {
                    foreach (ManagementObject Istance in mos)
                    {
                        LocalWMI.Tables["Win32_NetworkConnection"].Rows.Add(
                                                                        (from item in NetworkConnectionProperties
                                                                         select Istance[item]
                                                                        ).ToArray()
                                                                     );
                    }
                }
                catch (Exception ex)
                {
                    LocalWMI.Tables["Win32_NetworkConnection"].Rows.Add(new string[] { "Error" ,ex.Message.ToString() });
                }

            }
         **/

        public static void NetworkAdapterConfiguration()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration").Get();
                String[] NetworkAdapterConfigurationProperties = { "Description", "DHCPEnabled", "DHCPLeaseExpires", "DHCPLeaseObtained", "DHCPServer", "DNSDomain", "DNSDomainSuffixSearchOrder", "DNSHostName", "IPAddress", "IPConnectionMetric", "IPEnabled", "IPSubnet", "MACAddress", "ServiceName" };
                LocalWMI.Tables.Add(Utils.NewTable("Win32_NetworkAdapterConfiguration", NetworkAdapterConfigurationProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in NetworkAdapterConfigurationProperties select object.ReferenceEquals(Istance[item], null) ? " " : (Istance[item].GetType().Name.Equals("String[]") ? Utils.GetItemsFromMOArray(Istance[item]) : Istance[item])).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_NetworkAdapterConfiguration"].Rows.Add(
                                                                obj.ToArray()
                                                               );
                }
                reader.UpdateData("Win32_NetworkAdapterConfiguration");


            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "NetworkAdapterConfiguration " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_NetworkAdapterConfiguration", ex.Message.ToString());
            }
        }

        public static void NetworkAdapter()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter").Get();
                String[] NetworkAdapterProperties = { "AdapterType", "Name", "MACAddress", "Manufacturer", "NetConnectionID", "NetConnectionStatus", "ServiceName", "Speed", "TimeOfLastReset" };
                LocalWMI.Tables.Add(Utils.NewTable("Win32_NetworkAdapter", NetworkAdapterProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in NetworkAdapterProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_NetworkAdapter"].Rows.Add(
                                                                obj.ToArray()
                                                               );
                }
                reader.UpdateData("Win32_NetworkAdapter");


            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "NetworkAdapter " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_NetworkAdapter", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_DiskDrive. Elenca tutte le unità disco installate e le partizioni create su di esse
        /// </summary>
        public static void DiskDrive()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive").Get();

            String[] DiskDriveProperties = { "Caption", "DeviceID", "InterfaceType", "Manufacturer", "Model", "Partitions", "SerialNumber", "Size", "Status" };
            String[] LogicalDiskProperties = { "DiskDrive", "Compressed", "Description", "DeviceID", "FileSystem", "FreeSpace", "VolumeName", "VolumeSerialNumber" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_DiskDrive", DiskDriveProperties));
            LocalWMI.Tables.Add(Utils.NewTable("Win32_LogicalDisk", LogicalDiskProperties));
            try
            {
                int i = 1;
                int j = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in DiskDriveProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);

                    LocalWMI.Tables["Win32_DiskDrive"].Rows.Add(
                                                            obj.ToArray()
                                                         );

                    //Info su disco Caption InterfaceType Manufaturer Model Partitions Size DeviceID
                    ManagementObjectCollection DiskDriveToDiskPartition = new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + Istance["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get();
                    foreach (ManagementObject DrivePartition in DiskDriveToDiskPartition)
                    {
                        ManagementObjectCollection LogicalDiskToPartition = new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + DrivePartition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get();
                        foreach (ManagementObject LogicalDiskPartition in LogicalDiskToPartition)
                        {
                            
                            List<object> linqQuery = (from item in LogicalDiskProperties
                                                      where item != "DiskDrive"
                                                      select LogicalDiskPartition[item]
                                                     ).ToList();
                            linqQuery.Insert(0, Istance["DeviceID"].ToString());
                            linqQuery.Insert(0, DateTime.Today.ToShortDateString());
                            linqQuery.Insert(0, j++.ToString());
                            linqQuery.Insert(0, System.Environment.MachineName);
                            LocalWMI.Tables["Win32_LogicalDisk"].Rows.Add(linqQuery.ToArray());
                        }
                    }
                }

                reader.UpdateData("Win32_DiskDrive");

            }
            catch (Exception ex)
            {
#if debug 
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "DiskDrive " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_DiskDrive", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Group. Elenca tutti i gruppi utente presenti nel sistema
        /// </summary>
        public static void Group()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_Group").Get();

            String[] GroupProperties = { "Caption", "Domain", "LocalAccount", "Name", "SID", "SIDType", "Status" };

            Dictionary<string, string> SIDTypeValues = new Dictionary<string, string>()
            {
                 { "1", "SidTypeUser" }
                ,{ "2", "SidTypeGroup" }
                ,{ "3", "SidTypeDomain" }
                ,{ "4", "SidTypeAlias" }
                ,{ "5", "SidTypeWellKnownGroup" }
                ,{ "6", "SidTypeDeletedAccount" }
                ,{ "7", "SidTypeInvalid" }
                ,{ "8", "SidTypeUnknown" }
                ,{ "9", "SidTypeComputer" }
            };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_Group", GroupProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<string> obj = (from item in GroupProperties
                                        join st in SIDTypeValues on Istance["SIDType"].ToString() equals st.Key into stvalue
                                        from value in stvalue
                                        select item.Equals("SIDType") ? value.Value : Istance[item].ToString()
                                       ).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_Group"].Rows.Add(
                                                        obj.ToArray()
                                                     );
                }

                reader.UpdateData("Win32_Group");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "Group " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_Group", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_BaseBoard. Elenca delle informazioni sulla scheda madre
        /// </summary>
        public static void BaseBoard()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard").Get();

            String[] BaseBoardProperties = { "Caption", "Description", "Manufacturer", "Model", "Name", "PartNumber", "Product", "SerialNumber", "Status", "Version", "Weight", "Width" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_BaseBoard", BaseBoardProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in BaseBoardProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_BaseBoard"].Rows.Add(
                                                            obj.ToArray()
                                                          );
                }

                reader.UpdateData("Win32_BaseBoard");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "BaseBoard " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_BaseBoard", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_SoundDevice. Elenca delle informazioni sulla scheda audio
        /// </summary>
        public static void SoundDevice()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_SoundDevice").Get();

            String[] SoundDeviceProperties = { "Caption", "Description", "DMABufferSize", "Manufacturer", "Name", "PNPDeviceID", "ProductName", "Status" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_SoundDevice", SoundDeviceProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in SoundDeviceProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_SoundDevice"].Rows.Add(
                                                            obj.ToArray()
                                                          );
                }

                reader.UpdateData("Win32_SoundDevice");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "SoundDevice " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_SoundDevice", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_VideoController. Elenca delle informazioni sulla scheda video
        /// </summary>
        public static void VideoController()
        {
            //TODO: Implementare AcceleratorCapabilities e "ProtocolSupported", "VideoArchitecture",
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController").Get();

            String[] VideoControllerProperties = { "AcceleratorCapabilities", "AdapterDACType", "AdapterRAM", "CapabilityDescriptions", "Caption", "ColorTableEntries", "CurrentHorizontalResolution", "CurrentNumberOfColors", "CurrentRefreshRate", "CurrentVerticalResolution", "Description", "DriverDate", "DriverVersion", "MaxMemorySupported", "MaxRefreshRate", "MinRefreshRate", "Name", "PNPDeviceID", "ProtocolSupported", "VideoArchitecture", "VideoMemoryType", "VideoMode", "VideoProcessor" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_VideoController", VideoControllerProperties));
            Dictionary<string, string> MemType = new Dictionary<string, string>() {
                                                                                    {"1", "Other"}
                                                                                   ,{"2", "Unknown"}
                                                                                   ,{"3", "VRAM"}
                                                                                   ,{"4", "DRAM"}
                                                                                   ,{"5", "SRAM"}
                                                                                   ,{"6", "WRAM"}
                                                                                   ,{"7", "EDO RAM"}
                                                                                   ,{"8", "Burst Synchronous DRAM"}
                                                                                   ,{"9", "Pipelined Burst SRAM"}
                                                                                   ,{"10", "CDRAM"}
                                                                                   ,{"11", "3DRAM"}
                                                                                   ,{"12", "SDRAM"}
                                                                                   ,{"13", "SGRAM"}
                                                                                };

            Dictionary<string, string> VideoArch = new Dictionary<string, string>() {
                                                                                    {"1", "Other"}
                                                                                   ,{"2", "Unknown"}
                                                                                   ,{"3", "CGA"}
                                                                                   ,{"4", "EGA"}
                                                                                   ,{"5", "VGA"}
                                                                                   ,{"6", "SVGA"}
                                                                                   ,{"7", "MDA"}
                                                                                   ,{"8", "HGC"}
                                                                                   ,{"9", "MCGA"}
                                                                                   ,{"10", "8514A"}
                                                                                   ,{"11", "XGA"}
                                                                                   ,{"12", "Linear Frame Buffer"}
                                                                                   ,{"160","PC-98"}
                                                                                   ,};
            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in VideoControllerProperties
                                        join mt in MemType on Istance["VideoMemoryType"].ToString() equals mt.Key into mtValue
                                        join va in VideoArch on Istance["VideoArchitecture"].ToString() equals va.Key into vaValue
                                        from vaVal in vaValue
                                        from value in mtValue
                                        select item.Equals("VideoMemoryType") ? value.Value : (item.Equals("VideoArchitecture") ? vaVal.Value : Istance[item])).ToList();

                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_VideoController"].Rows.Add(
                                                                obj.ToArray()
                                                              );
                }

                reader.UpdateData("Win32_VideoController");

            }
            catch (Exception ex)
            {
#if debug          
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "VideoController " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_VideoController", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_CDROMDrive. Elenca tutte le unità CDROM presenti nel sistema
        /// </summary>
        public static void CDROMDrive()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive").Get();

            String[] CDROMDriveProperties = { "Caption", "Description", "DeviceID", "Drive", "MediaLoaded", "MediaType", "SerialNumber", "Volumename" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_CDROMDrive", CDROMDriveProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in CDROMDriveProperties
                                        select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_CDROMDrive"].Rows.Add(
                                                            obj.ToArray()
                                                          );
                }

                reader.UpdateData("Win32_CDROMDrive");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "CDROMDrive " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_CDROMDrive", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_ComputerSystem. Elenca tutte le informazioni di un commputer
        /// </summary>
        public static void ComputerSystem()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem").Get();

            String[] ComputerSystemProperties = { "CurrentTimeZone", "Domain", "DomainRole", "Manufacturer", "Model", "Name", "NumberOfProcessors", "PartOfDomain", "PrimaryOwnerName", "SystemType", "TotalPhysicalMemory", "UserName", "Workgroup" };
            Dictionary<string, string> DomainRole = new Dictionary<string, string>() 
            {
                 {"0", "Standalone Workstation"}
                ,{"1", "Member Workstation"}
                ,{"2", "Standalone Server"}
                ,{"3", "Member Server"}
                ,{"4", "Backup Domain Controller"}
                ,{"5", "Primary Domain Controller"}
            };
            LocalWMI.Tables.Add(Utils.NewTable("Win32_ComputerSystem", ComputerSystemProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in ComputerSystemProperties
                                        join dr in DomainRole on Istance["DomainRole"].ToString() equals dr.Key into drValue
                                        from value in drValue
                                        select 
                                                object.ReferenceEquals(Istance[item], null) ?  " "  : 
                                                Istance[item].GetType().Name.Equals("String[]") ? Utils.GetItemsFromMOArray(Istance[item]) : 
                                                item.Equals("DomainRole") ? value.Value : Istance[item] ).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_ComputerSystem"].Rows.Add(
                                                                obj.ToArray()
                                                              );
                }

                reader.UpdateData("Win32_ComputerSystem");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "ComputerSystem " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_ComputerSystem", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Environment. Elenca le variabili d'ambiente del sistema
        /// </summary>
        //public static void Environment()
        //{
        //    mos = new ManagementObjectSearcher("SELECT * FROM Win32_Environment").Get();

        //    String[] EnvironmentProperties = { "Caption", "Description", "Name", "Status", "UserName" };

        //    LocalWMI.Tables.Add(Utils.NewTable("Win32_Environment", EnvironmentProperties));

        //    try
        //    {
        //        foreach (ManagementObject Istance in mos)
        //        {
        //            List<object> obj = (from item in EnvironmentProperties select Istance[item]).ToList();
        //            obj.Insert(0, System.Environment.MachineName);
        //            LocalWMI.Tables["Win32_Environment"].Rows.Add(
        //                                                    obj.ToArray()
        //                                                  );
        //        }
        //        
        //        reader.UpdateData("Win32_NetworkAdapter");
        //        
        //    }
        //    catch (Exception ex)
        //    {
        //        LocalWMI.Tables["Win32_Environment"].Rows.Add(new string[] { "Error", ex.Message.ToString() });
        //    }
        //}

        /// <summary>
        /// Classe: Win32_FloppyDrive. Elenca delle info sulle unità floppy presenti nel computer
        /// </summary>
        public static void FloppyDrive()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_FloppyDrive").Get();

            String[] FloppyDriveProperties = { "Caption", "Description", "DeviceID", "MaxBlockSize", "Name", "NeedsCleaning", "Status" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_FloppyDrive", FloppyDriveProperties));

            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in FloppyDriveProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_FloppyDrive"].Rows.Add(
                                                            obj.ToArray()
                                                           );
                }

                reader.UpdateData("Win32_FloppyDrive");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "FloppyDrive " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_FloppyDrive", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_IP4RouteTable. Rappresenta le informazioni che governano l'instradamento dei pacchetti in una rete
        /// </summary>
        public static void IP4RouteTable()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_IP4RouteTable").Get();

            String[] IP4RouteTableProperties = { "Caption", "Description", "Destination", "Information", "Name", "Protocol", "Status", "Type" };

            LocalWMI.Tables.Add(Utils.NewTable("Win32_IP4RouteTable", IP4RouteTableProperties));
            Dictionary<string, string> IpType = new Dictionary<string, string>() {
                                                                                    {"1", "Other"}
                                                                                   ,{"2", "Invalid"}
                                                                                   ,{"3", "Direct"}
                                                                                   ,{"4", "Indirect"}
                                                                                };
            try
            {
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in IP4RouteTableProperties
                                        join it in IpType on Istance["Type"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("Type") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_IP4RouteTable"].Rows.Add(
                                                               obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_IP4RouteTable");

            }
            catch (Exception ex)
            {
#if debug          
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "IP4RouteTable " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_IP4RouteTable", ex.Message.ToString());
            }


        }

        /// <summary>
        /// Classe: Win32_PhysicalMemory. Elenca delle info sulla memoria fisica
        /// </summary>
        public static void PhysicalMemory()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMemory").Get();

                String[] PhysicalMemoryProperties = { "Capacity", "Caption", "DataWidth", "Description", "FormFactor", "Manufacturer", "MemoryType", "Name", "Speed", "TotalWidth", "TypeDetail" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_PhysicalMemory", PhysicalMemoryProperties));
                Dictionary<string, string> TypeDetail = new Dictionary<string, string>() {
                                                                                    {"0", "Null"}
                                                                                   ,{"1", "Reserved"}
                                                                                   ,{"2", "Other"}
                                                                                   ,{"4", "Unknown"}
                                                                                   ,{"8", "Fast-paged"}
                                                                                   ,{"16", "Static column"}
                                                                                   ,{"32", "Pseudo-static"}
                                                                                   ,{"64", "RAMBUS"}
                                                                                   ,{"128", "Synchronous"}
                                                                                   ,{"256", "CMOS"}
                                                                                   ,{"512", "EDO"}
                                                                                   ,{"1024", "Window DRAM"}
                                                                                   ,{"2048", "Cache DRAM"}
                                                                                   ,{"4096", "Nonvolatile"}
                                                                                };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in PhysicalMemoryProperties
                                        join it in TypeDetail on Istance["TypeDetail"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("TypeDetail") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_PhysicalMemory"].Rows.Add(
                                                              obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_PhysicalMemory");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "PhysicalMemory " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_PhysicalMemory", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Processor. Elenca delle info sul processore
        /// </summary>
        public static void Processor()
        {
            try
            {
                //TODO: Implementare Family e  "ProcessorType",

                mos = new ManagementObjectSearcher("SELECT * FROM Win32_Processor").Get();

                String[] ProcessorProperties = { "Architecture", "Caption", "CpuStatus", "CurrentClockSpeed", "CurrentVoltage", "DataWidth", "Description", "Family", "L2CacheSize", "L2CacheSpeed", "L3CacheSize", "L3CacheSpeed", "Manufacturer", "MaxClockSpeed", "Name", "NumberOfCores", "NumberOfLogicalProcessors", "ProcessorId", "ProcessorType", "Role", "SocketDesignation", "Version", "VoltageCaps" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_Processor", ProcessorProperties));
                Dictionary<string, string> Architecture = new Dictionary<string, string>() {
                                                                                    {"0", "x86"}
                                                                                   ,{"1", "MIPS"}
                                                                                   ,{"2", "Alpha"}
                                                                                   ,{"3", "PowerPC"}
                                                                                   ,{"6", "Itanium-based systems"}
                                                                                   ,{"9", "x86"}

                                                                                };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in ProcessorProperties
                                        join it in Architecture on Istance["Architecture"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("Architecture") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_Processor"].Rows.Add(
                                                            obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_Processor");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "Processor " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_Processor", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Printer. Elenca delle info sulle stampanti
        /// </summary>
        public static void Printer()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_Printer").Get();

                String[] PrinterProperties = { "Capabilities", "Caption", "DefaultPaperType", "DefaultCopies", "Description", "Hidden", "Location", "MarkingTechnology", "MaxCopies", "MaxSizeSupported", "Name", "Network", "PaperSizesSupported", "PortName", "PrinterState", "PrinterStatus", "Queued" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_Printer", PrinterProperties));
                Dictionary<string, string> PrinterStatus = new Dictionary<string, string>() {
                                                                                    {"0", "Unknown"}
                                                                                   ,{"1", "Other"}
                                                                                   ,{"2", "Unknown"}
                                                                                   ,{"3", "Idle"}
                                                                                   ,{"4", "Printing"}
                                                                                   ,{"5", "Warming Up"}
                                                                                   ,{"6", "Stopped printing"}
                                                                                   ,{"7", "Offline"}

                                                                                };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in PrinterProperties
                                        join it in PrinterStatus on Istance["PrinterStatus"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select object.ReferenceEquals(Istance[item], null) ?  " "  : 
                                        Istance[item].GetType().Name.Equals("String[]") ? Utils.GetItemsFromMOArray(Istance[item]) : 
                                        item.Equals("PrinterStatus") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_Printer"].Rows.Add(
                        obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_Printer");

            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "Printer " + ex.Message + "\r\n");
#endif       
                Utils.InsertException("Win32_Printer", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_PnPEntity. Elenca delle info sulle periferiche pnp collegate
        /// </summary>
        public static void PnPEntity()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity").Get();
                String[] PnPEntityProperties = { "Caption", "Description", "DeviceID", "Manufacturer", "Name", "Service", "Status" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_PnPEntity", PnPEntityProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in PnPEntityProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_PnPEntity"].Rows.Add(

                                                                obj.ToArray()
                                                               );

                }

                reader.UpdateData("Win32_PnPEntity");

            }
            catch (Exception ex)
            {
#if debug          
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "PnPEntity " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_PnPEntity", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Share. Elenca delle info sulle periferiche condivise
        /// </summary>
        public static void Share()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_Share").Get();
                String[] ShareProperties = { "Caption", "MaximumAllowed", "Path", "Status", "Type" };
                Dictionary<string, string> ShareType = new Dictionary<string, string>() {
                                                                                    {"0", "Disk Drive"}
                                                                                   ,{"1", "Print Queue"}
                                                                                   ,{"2", "Device"}
                                                                                   ,{"3", "IPC"}
                                                                                   ,{"2147483648 ", "Disk Drive Admin"}
                                                                                   ,{"2147483649", "Print Queue Admin"}
                                                                                   ,{"2147483650", "Device Admin"}
                                                                                   ,{"2147483651", "IPC Admin"}

                                                                                };
                LocalWMI.Tables.Add(Utils.NewTable("Win32_Share", ShareProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in ShareProperties
                                        join it in ShareType on Istance["Type"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("Type") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_Share"].Rows.Add(
                                                                obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_Share");

            }
            catch (Exception ex)
            {
#if debug                
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "Share " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_Share", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_Product. Elenca delle info su tutti i programmi installati
        /// </summary>
        public static void Product()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product").Get();
                String[] ProductProperties = { "Caption", "Description", "InstallDate", "InstallLocation", "InstallState", "Name", "Vendor", "Version" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_Product", ProductProperties));
                Dictionary<string, string> InstallState = new Dictionary<string, string>() {
                                                                                    {"-6", "Bad Configuration"}
                                                                                   ,{"-2", "Invalid Argument"}
                                                                                   ,{"-1", "Unknown Package"}
                                                                                   ,{"1",  "Advertised"}
                                                                                   ,{"2",  "Absent"}
                                                                                   ,{"5",  "Installed"}

                                                                                };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in ProductProperties
                                        join it in InstallState on Istance["InstallState"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("InstallState") ? value.Value : Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_Product"].Rows.Add(
                                                        obj.ToArray()
                                                       );

                }

                reader.UpdateData("Win32_Product");

            }
            catch (Exception ex)
            {
#if debug                
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "Product " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_Product", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_OperatingSystem. Elenca delle info sul sistema operativo in xp e di tutti i so installati in vista e superiori
        /// </summary>
        public static void OperatingSystem()
        {
            try
            {
                // TODO: SuiteMask ProductType
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get();
                String[] OperatingSystemProperties = { "BootDevice", "BuildNumber", "BuildType", "Caption", "CountryCode", "CSDVersion", "CSName", "Description", "InstallDate", "LastBootUpTime", "Manufacturer", "MaxNumberOfProcesses", "MaxProcessMemorySize", "Name", "NumberOfLicensedUsers", "Organization", "OSType", "Primary", "ProductType", "RegisteredUser", "SerialNumber", "SuiteMask", "SystemDirectory", "SystemDrive", "Version" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_OperatingSystem", OperatingSystemProperties));

                Dictionary<string, string> OSType = new Dictionary<string, string>() {
                                                                                    {"0", "Unknown"}
                                                                                   ,{"1", "Other"}
                                                                                   ,{"2", "MACROS"}
                                                                                   ,{"3",  "ATTUNIX"}
                                                                                   ,{"4",  "DGUX"}
                                                                                   ,{"5",  "DECNT"}
                                                                                   ,{"6", "Digital UNIX"}
                                                                                   ,{"7",  "OpenVMS"}
                                                                                   ,{"8", "HPUX"}
                                                                                   ,{"9", "AIX"}
                                                                                   ,{"10", "MVS"}
                                                                                   ,{"11",  "OS400"}
                                                                                   ,{"12",  "OS/2"}
                                                                                   ,{"13",  "JavaVM"}
                                                                                   ,{"14", "MSDOS"}
                                                                                   ,{"15",  "WIN3x"}
                                                                                   ,{"16", "WIN95"}
                                                                                   ,{"17", "WIN98"}
                                                                                   ,{"18", "WINNT"}
                                                                                   ,{"19",  "WINCE"}
                                                                                   ,{"20",  "NCR3000"}
                                                                                   ,{"21",  "NETWARE"}
                                                                                   ,{"22",  "OSF"}
                                                                                   ,{"23", "DC/OS"}
                                                                                   ,{"24",  "Reliant UNIX"}
                                                                                   ,{"25", "SCO UnixWare"}
                                                                                   ,{"26", "SCO OpenServer"}
                                                                                   ,{"27", "Sequent"}
                                                                                   ,{"28",  "IRIX"}
                                                                                   ,{"29",  "Solaris"}
                                                                                   ,{"30",  "SunOS"}
                                                                                   ,{"31", "U6000"}
                                                                                   ,{"32", "ASERIES"}
                                                                                   ,{"33", "TandemNSK"}
                                                                                   ,{"34",  "TandemNT"}
                                                                                   ,{"35",  "BS2000"}
                                                                                   ,{"36",  "LINUX"}
                                                                                   ,{"37", "Lynx"}
                                                                                   ,{"38",  "XENIX"}
                                                                                   ,{"39", "VM/ESA"}
                                                                                   ,{"40", "Interactive UNIX"}
                                                                                   ,{"41", "BSDUNIX"}
                                                                                   ,{"42",  "FreeBSD"}
                                                                                   ,{"43",  "NetBSD"}
                                                                                   ,{"44",  "GNU Hurd"}
                                                                                   ,{"45", "OS9"}
                                                                                   ,{"46",  "MACH Kernel"}
                                                                                   ,{"47", "Inferno"}
                                                                                   ,{"48", "QNX"}
                                                                                   ,{"49",  "EPOC"}
                                                                                   ,{"50",  "IxWorks"}
                                                                                   ,{"51",  "VxWorks"}
                                                                                   ,{"52", "MiNT"}
                                                                                   ,{"53",  "BeOS"}
                                                                                   ,{"54", "HP MPE"}
                                                                                   ,{"55", "NextStep"}
                                                                                   ,{"56", "PalmPilot"}
                                                                                   ,{"57",  "Rhapsody"}
                                                                                };

                Dictionary<string, string> ProductType = new Dictionary<string, string>(){
                                                                                    {"1", "Workstation"}
                                                                                   ,{"2", "Domain Controller"}
                                                                                   ,{"3", "Server"}
                                                                                    };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in OperatingSystemProperties
                                        join it in OSType on Istance["OSType"].ToString() equals it.Key into itValue
                                        join it in ProductType on Istance["ProductType"].ToString() equals it.Key into it2Value
                                        from OSValue in itValue
                                        from ProdValue in it2Value
                                        select item.Equals("OSType") ? OSValue.Value : item.Equals("ProductType") ? ProdValue.Value : Istance[item]
                                                                ).ToList(); 
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_OperatingSystem"].Rows.Add(
                                                                obj.ToArray()
                                                               );
                }

                reader.UpdateData("Win32_OperatingSystem");

            }
            catch (Exception ex)
            {
#if debug                
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "OperatingSystem " + ex.Message + "\r\n");
#endif       
                Utils.InsertException("Win32_OperatingSystem", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_LogonSession. Elenca delle info sugli utenti collegati
        /// </summary>
        public static void LogonSession()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_LogonSession").Get();
                String[] LogonSessionProperties = { "AuthenticationPackage", "Caption", "Description", "LogonId", "LogonType", "Name", "Status" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_LogonSession", LogonSessionProperties));
                Dictionary<string, string> LogonType = new Dictionary<string, string>() {
                                                                                    {"0", "System account"}
                                                                                   ,{"2", "Interactive"}
                                                                                   ,{"3", "Network"}
                                                                                   ,{"4",  "Batch"}
                                                                                   ,{"5",  "Service"}
                                                                                   ,{"6",  "Proxy"}
                                                                                   ,{"7", "Unlock"}
                                                                                   ,{"8",  "NetworkCleartext"}
                                                                                   ,{"9", "NewCredentials"}
                                                                                   ,{"10", "RemoteInteractive"}
                                                                                   ,{"11", "CachedInteractive"}
                                                                                   ,{"12",  "CachedRemoteInteractive"}
                                                                                   ,{"13",  "CachedUnlock"}
                                                                                       };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in LogonSessionProperties
                                        join it in LogonType on Istance["LogonType"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("LogonType") ? value.Value : Istance[item]
                                                                ).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_LogonSession"].Rows.Add(
                                                               obj.ToArray()
                                                              );

                }

                reader.UpdateData("Win32_LogonSession");


            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "LogonSession " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_LogonSession", ex.Message.ToString());
            }
        }


        /// <summary>
        /// Classe: Win32_ParallelPort. Restituisce le info sulle porte parallele
        /// </summary>
        public static void ParallelPort()
        {
            mos = new ManagementObjectSearcher("SELECT * FROM Win32_ParallelPort").Get();
            try
            {
                String[] ParallelPortProperties = { "Capabilities", "Caption", "Description", "DeviceID", "DMASupport", "MaxNumberControlled", "Name", "ProtocolSupported" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_ParallelPort", ParallelPortProperties));
                Dictionary<string, string> ProtocolSupported = new Dictionary<string, string>() {
                                                                                    {"1", "Other"},
                                                                                    {"2", "Unknown"},
                                                                                    {"3", "EISA"},
                                                                                    {"4", "ISA"},
                                                                                    {"5", "PCI"},
                                                                                    {"6", "ATA/ATAPI"},
                                                                                    {"7", "Flexible Diskette"},
                                                                                    {"8 ", "1496"},
                                                                                    {"9", "SCSI Parallel Interface"},
                                                                                    {"10",	"SCSI Fibre Channel Protocol"},
                                                                                    {"11",	"SCSI Serial Bus Protocol"},
                                                                                    {"12", "SCSI Serial Bus Protocol-2 (1394)"},
                                                                                    {"13", "SCSI Serial Storage Architecture"},
                                                                                    {"14", "VESA"},
                                                                                    {"15", "PCMCIA"},
                                                                                    {"16", "Universal Serial Bus"},
                                                                                    {"17", "Parallel Protocol"},
                                                                                    {"18", "ESCON"},
                                                                                    {"19", "Diagnostic"},
                                                                                    {"20", "I2C"},
                                                                                    {"21", "Power"},
                                                                                    {"22", "HIPPI"},
                                                                                    {"23", "MultiBus"},
                                                                                    {"24", "VME"},
                                                                                    {"25", "IPI"},
                                                                                    {"26", "IEEE-488"},
                                                                                    {"27", "RS232"},
                                                                                    {"28", "IEEE 802.3 10BASE5"},
                                                                                    {"29", "IEEE 802.3 10BASE2"},
                                                                                    {"30", "IEEE 802.3 1BASE5"},
                                                                                    {"31", "IEEE 802.3 10BROAD36"},
                                                                                    {"32", "IEEE 802.3 100BASEVG"},
                                                                                    {"33", "IEEE 802.5 Token-Ring"},
                                                                                    {"34", "ANSI X3T9.5 FDDI"},
                                                                                    {"35", "MCA"},
                                                                                    {"36", "ESDI"},
                                                                                    {"37", "IDE"},
                                                                                    {"38", "CMD"},
                                                                                    {"39", "ST506"},
                                                                                    {"40", "DSSI"},
                                                                                    {"41", "QIC2"},
                                                                                    {"42", "Enhanced ATA/IDE"},
                                                                                    {"43", "AGP"},
                                                                                    {"44", "TWIRP (two-way infrared)"},
                                                                                    {"45", "FIR (fast infrared)"},
                                                                                    {"46", "SIR (serial infrared)"},
                                                                                    {"47", "IrBus"}
                                                                                       };
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in ParallelPortProperties
                                        join it in ProtocolSupported on Istance["ProtocolSupported"].ToString() equals it.Key into itValue
                                        from value in itValue
                                        select item.Equals("ProtocolSupported") ? value.Value : Istance[item]
                                                                ).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_ParallelPort"].Rows.Add(
                                                              obj.ToArray()
                                                              );

                }
                reader.UpdateData("Win32_ParallelPort");
            }
            catch (Exception ex)
            {
#if debug
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "ParallelPort " + ex.Message + "\r\n");
#endif                
                Utils.InsertException("Win32_ParallelPort", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_SerialPort. Restituisce le info sulle porte seriali
        /// </summary>
        public static void SerialPort()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_SerialPort").Get();
                String[] SerialPortProperties = { "Capabilities", "Caption", "Description", "DeviceID", "MaxBaudRate", "MaximumInputBufferSize", "MaximumOutputBufferSize", "ProtocolSupported", "ProviderType", "SupportsSpecialCharacters" };

                LocalWMI.Tables.Add(Utils.NewTable("Win32_SerialPort", SerialPortProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in SerialPortProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_SerialPort"].Rows.Add(
                                                                obj.ToArray()
                                                               );

                }
                reader.UpdateData("Win32_SerialPort");


            }
            catch (Exception ex)
            {
#if debug                
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "SerialPort " + ex.Message + "\r\n");
#endif                
                Utils.InsertException("Win32_SerialPort", ex.Message.ToString());
            } 
        }

        /// <summary>
        /// Classe: Win32_UserAccount
        /// </summary>
        public static void UserAccount()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_UserAccount").Get();
                String[] UserAccountProperties = { "Caption", "Disabled", "Domain", "InstallDate", "LocalAccount", "Lockout", "Name", "PasswordChangeable", "PasswordExpires", "PasswordRequired", "Status" };
                LocalWMI.Tables.Add(Utils.NewTable("Win32_UserAccount", UserAccountProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in UserAccountProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_UserAccount"].Rows.Add(

                                                               obj.ToArray()
                                                               );

                }
                reader.UpdateData("Win32_UserAccount");


            }
            catch (Exception ex)
            {
#if debug                
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "UserAccount " + ex.Message + "\r\n");
#endif                
                Utils.InsertException("Win32_UserAccount", ex.Message.ToString());
            }
        }

        /// <summary>
        /// Classe: Win32_NetworkLoginProfile
        /// </summary>
        public static void NetworkLoginProfile()
        {
            try
            {
                mos = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkLoginProfile").Get();
                String[] NetworkLoginProfileProperties = { "HomeDirectory", "HomeDirectoryDrive", "LastLogoff", "LastLogon", "LogonHours", "LogonServer", "Name", "NumberOfLogons", "PasswordAge", "Privileges", "Profile", "UserType", "Workstations" };
                LocalWMI.Tables.Add(Utils.NewTable("Win32_NetworkLoginProfile", NetworkLoginProfileProperties));
                int i = 1;
                foreach (ManagementObject Istance in mos)
                {
                    List<object> obj = (from item in NetworkLoginProfileProperties select Istance[item]).ToList();
                    obj.Insert(0, DateTime.Today.ToShortDateString());
                    obj.Insert(0, i++.ToString());
                    obj.Insert(0, System.Environment.MachineName);
                    LocalWMI.Tables["Win32_NetworkLoginProfile"].Rows.Add(
                                                                obj.ToArray()
                                                               );

                }

                reader.UpdateData("Win32_NetworkLoginProfile");


            }
            catch (Exception ex)
            {
#if debug          
                System.IO.File.AppendAllText(InstallationFolder+"Log.txt", "NetworkLoginProfile " + ex.Message + "\r\n");
#endif
                Utils.InsertException("Win32_NetworkLoginProfile", ex.Message.ToString());
            }
        }

    }
}
